﻿using System;
using System.Text.Json;
using System.Xml.Linq;

namespace System.Text.Json
{
    /// <summary>
    /// 针对<see langword="System.Text.Json"/>进行扩展
    /// </summary>
    /// <creator>marc</creator>
    public static class JsonExtensions
    {
        /// <summary>
        /// 判断一个字符串是否是有效的json格式
        /// </summary>
        /// <param name="str">待判断的字符串</param>
        /// <returns>若字符串是有效json，则返回<see langword="true"/>，反之<see langword="false"/></returns>
        public static bool IsJson(this string str)
        {
            try
            {
                JsonDocument.Parse(str);
                return true;
            }
            catch (JsonException)
            {
                return false;
            }
        }

        /// <summary>
        /// 将对象序列化为 JSON 字符串。
        /// </summary>
        /// <param name="obj">要序列化为JSON的对象。</param>
        public static string ToJson<T>(this T obj)
        {
            return JsonSerializer.Serialize(obj);
        }

        /// <summary>
        /// 将对象序列化为 JSON 字符串。
        /// </summary>
        /// <param name="obj">要序列化为JSON的对象。</param>
        /// <param name="options">在反序列化过程中使用的 JsonSerializerOptions。</param>
        public static string ToJson<T>(this T obj, JsonSerializerOptions options)
        {
            return JsonSerializer.Serialize(obj, options);
        }

        /// <summary>
        /// 将 JSON 字符串反序列化为指定类型的对象。
        /// </summary>
        public static T FromJson<T>(this string json)
        {
            return JsonSerializer.Deserialize<T>(json);
        }

        /// <summary>
        /// 将 JSON 字符串反序列化为指定类型的对象。
        /// </summary>
        /// <param name="json">要反序列化的 JSON 字符串。</param>
        /// <param name="options">在反序列化过程中使用的 JsonSerializerOptions。</param>
        public static T FromJson<T>(this string json, JsonSerializerOptions options)
        {
            return JsonSerializer.Deserialize<T>(json, options);
        }

        /// <summary>
        /// 将 JSON 字符串反序列化为动态对象。
        /// </summary>
        public static dynamic FromJson(this string json)
        {
            return JsonSerializer.Deserialize<dynamic>(json);
        }

        /// <summary>
        /// 将 JSON 字符串反序列化为动态对象。
        /// </summary>
        /// <param name="json">要反序列化的 JSON 字符串。</param>
        /// <param name="options">在反序列化过程中使用的 JsonSerializerOptions。</param>
        public static dynamic FromJson(this string json, JsonSerializerOptions options)
        {
            return JsonSerializer.Deserialize<dynamic>(json, options);
        }

        /// <summary>
        /// 将XML字符串转换为JSON字符串
        /// </summary>
        /// <param name="xml">xml字符串</param>
        /// <param name="options">格式化参数</param>
        public static string ToJson(this string xml, JsonSerializerOptions options = default)
        {
            var xmlDoc = XDocument.Parse(xml);

            if (options == default)
            {
                options = new System.Text.Json.JsonSerializerOptions
                {
                    //启用 ReferenceHandler.Preserve是转化为xml的关键点
                    ReferenceHandler = System.Text.Json.Serialization.ReferenceHandler.Preserve,
                    WriteIndented = true,
                    PropertyNamingPolicy = System.Text.Json.JsonNamingPolicy.CamelCase,
                    PropertyNameCaseInsensitive = true,
                    Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
                };
            }

            var json = System.Text.Json.JsonSerializer.Serialize(xmlDoc, options);
            return json;
        }
    }
}
